package com.example.demo.controller;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/documents")
public class DocumentStorageController {

    // 基础存储目录（项目根目录下的documents）
    private final Path basePath = Paths.get("documents").toAbsolutePath().normalize();
    private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    // 允许的文件类型白名单
    private static final List<String> ALLOWED_CONTENT_TYPES = Arrays.asList(
            "text/plain",
            "application/msword",
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
    );

    @PostMapping("/upload/{folder}")
    public ResponseEntity<?> uploadFile(
            @PathVariable String folder,
            @RequestParam("file") MultipartFile file) {
        try {
            // 构建完整存储路径
            Path uploadPath = basePath.resolve(folder).normalize();

            // 自动创建上传目录
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 校验文件是否为空
            if (file.isEmpty()) {
                return ResponseEntity.badRequest().body("File is empty");
            }

            // 校验文件类型
            if (!ALLOWED_CONTENT_TYPES.contains(file.getContentType())) {
                return ResponseEntity.badRequest().body("Unsupported file type");
            }

            // 生成带日期的安全文件名
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.contains(".")
                    ? originalFilename.substring(originalFilename.lastIndexOf("."))
                    : "";
            String dateSuffix = "-" + LocalDate.now().format(dateFormatter);
            String filename = UUID.randomUUID() + dateSuffix + extension;

            // 保存文件
            Path targetLocation = uploadPath.resolve(filename);
            file.transferTo(targetLocation);

            return ResponseEntity.ok().body(new FileUploadResponse(
                    folder,
                    filename,
                    originalFilename,
                    file.getContentType(),
                    file.getSize()
            ));
        } catch (IOException ex) {
            return ResponseEntity.internalServerError().body("Upload failed: " + ex.getMessage());
        }
    }

    @GetMapping("/preview/{folder}/{filename}")
    public ResponseEntity<?> previewFile(
            @PathVariable String folder,
            @PathVariable String filename) {
        try {
            Path filePath = validateAndGetPath(folder, filename);
            Resource resource = new UrlResource(filePath.toUri());

            if (!resource.exists()) {
                return ResponseEntity.notFound().build();
            }

            // 文本文件预览
            if (filename.endsWith(".txt")) {
                String content = new String(Files.readAllBytes(filePath), StandardCharsets.UTF_8);
                return ResponseEntity.ok()
                        .contentType(MediaType.TEXT_PLAIN)
                        .body(content);
            }
            // DOCX文件预览
            else if (filename.endsWith(".docx")) {
                try (InputStream is = resource.getInputStream()) {
                    XWPFDocument docx = new XWPFDocument(is);
                    XWPFWordExtractor extractor = new XWPFWordExtractor(docx);
                    String text = extractor.getText();
                    return ResponseEntity.ok()
                            .contentType(MediaType.TEXT_PLAIN)
                            .body(text);
                }
            }
            // DOC文件预览
            else if (filename.endsWith(".doc")) {
                try (InputStream is = resource.getInputStream()) {
                    HWPFDocument doc = new HWPFDocument(is);
                    WordExtractor extractor = new WordExtractor(doc);
                    String text = extractor.getText();
                    return ResponseEntity.ok()
                            .contentType(MediaType.TEXT_PLAIN)
                            .body(text);
                }
            }
            // 其他文件返回基本信息
            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(new FileInfo(
                            folder,
                            filename,
                            Files.probeContentType(filePath),
                            resource.contentLength()
                    ));
        } catch (Exception ex) {
            return ResponseEntity.internalServerError().body("Preview error: " + ex.getMessage());
        }
    }

    @GetMapping("/download/{folder}/{filename}")
    public ResponseEntity<Resource> downloadFile(
            @PathVariable String folder,
            @PathVariable String filename) {
        try {
            Path filePath = validateAndGetPath(folder, filename);
            Resource resource = new UrlResource(filePath.toUri());

            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            "attachment; filename=\"" + filename + "\"")
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(resource);
        } catch (Exception ex) {
            return ResponseEntity.internalServerError().build();
        }
    }

    // 路径安全验证
    private Path validateAndGetPath(String folder, String filename) throws IOException {
        Path folderPath = basePath.resolve(folder).normalize();
        if (!folderPath.startsWith(basePath)) {
            throw new SecurityException("Invalid folder path");
        }

        Path filePath = folderPath.resolve(filename).normalize();
        if (!filePath.startsWith(folderPath)) {
            throw new SecurityException("Invalid file path");
        }
        return filePath;
    }

    // 文件上传响应DTO
    private static class FileUploadResponse {
        private final String folder;
        private final String serverFilename;
        private final String originalFilename;
        private final String contentType;
        private final long size;

        public FileUploadResponse(String folder, String serverFilename,
                                  String originalFilename, String contentType, long size) {
            this.folder = folder;
            this.serverFilename = serverFilename;
            this.originalFilename = originalFilename;
            this.contentType = contentType;
            this.size = size;
        }

        // Getters
        public String getFolder() { return folder; }
        public String getServerFilename() { return serverFilename; }
        public String getOriginalFilename() { return originalFilename; }
        public String getContentType() { return contentType; }
        public long getSize() { return size; }
    }

    // 文件信息DTO
    private static class FileInfo {
        private final String folder;
        private final String name;
        private final String type;
        private final long size;

        public FileInfo(String folder, String name, String type, long size) {
            this.folder = folder;
            this.name = name;
            this.type = type;
            this.size = size;
        }

        // Getters
        public String getFolder() { return folder; }
        public String getName() { return name; }
        public String getType() { return type; }
        public long getSize() { return size; }
    }
}